package ws.utils.io;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStreamWriter;
import java.io.Serializable;
import java.io.Writer;

/**
 * This class provides some methods to read/write data into/from files.
 *
 * @author Wilson Santos, 36228 <wilson.santos@ua.pt>
 */
public class FileUtil {

  /** Singleton class. */
  private FileUtil() {
    assert false : "FileUtil is a singleton class.";
  }

  /**
   * Dump a object's state to a file.
   *
   * @param obj object to be dumped.
   * @param filename file name of the output file.
   *
   * @throws FileNotFoundException if can't find the destination file.
   * @throws IOException If an I/O error occurs.
   */
  public static void dumpObject(Serializable obj, String filename) throws FileNotFoundException, IOException {
    FileOutputStream fout = new FileOutputStream(filename);
    ObjectOutputStream oos = new ObjectOutputStream(fout);
    oos.writeObject(obj);
    oos.close();
  }

  /**
   * Read the object's state from a file.
   *
   * @param filename name of the file that has the object's state.
   *
   * @return object read.
   *
   * @throws FileNotFoundException if can't find the file with the object's state.
   * @throws IOException if an I/O error occurs while reading object.
   */
  public static Object readObject(String filename) throws FileNotFoundException, IOException {
    Object ret = null;
    File tempFile = new File(filename);

    FileInputStream fin = new FileInputStream(tempFile);
    ObjectInputStream ois = new ObjectInputStream(fin);
    try {
      ret = ois.readObject();
    } catch (final ClassNotFoundException ex) {
      // as long as the class of the object to be read is on classpath, won't cause any problems.
      throw new RuntimeException(ex);
    }
    ois.close();
    return ret;
  }

  /**
   * Write plain text (some {@code String}) to file.
   * 
   * @param text text to be written.
   *
   * @throws FileNotFoundException if can't find the destination file.
   * @throws IOException If an I/O error occurs.
   */
  public static void writeTextToFile(String text, String filename) throws FileNotFoundException, IOException {
    File tempFile = new File(filename);
    FileOutputStream fos = new FileOutputStream(tempFile);
    Writer out = new OutputStreamWriter(fos);
    try {
      out.write(text);
    } finally {
      out.close();
    }
  }

  /**
   * Append plain text (some {@code String}) to file.
   *
   * @param text text to be written.
   *
   * @throws IOException If an I/O error occurs
   */
  public static void appendTextToFile(String text, String filename) throws IOException {
    File tempFile = new File(filename);
    FileWriter fstream = new FileWriter(tempFile, true);
    BufferedWriter out = new BufferedWriter(fstream);

    out.write(text);
    out.close();
  }
}
